package com.laxcen.basiclib.utils;

import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;

import com.google.android.material.snackbar.Snackbar;
import com.laxcen.basiclib.BaseApp;
import com.laxcen.basiclib.BaseConst;
import com.laxcen.basiclib.R;
import com.laxcen.basiclib.core.bridgewebview.bean.H5AppConfig;
import com.laxcen.basiclib.engine.ApiEngine;
import com.laxcen.basiclib.ui.dialog.AlertDialog;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;


/**
 * Create by 游德禄 on 2019-9-3
 * 公共工具
 */
public class CommonUtil {

    /**
     * 简短提示
     * @param mContext
     * @param text
     */
    public static void tip(Context mContext, String text) {
        Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
    }

    /**
     * 由下面弹出提示
     * @param view
     * @param text
     */
    public static void tipBottom(View view, String text) {
        Snackbar.make(view, text, Snackbar.LENGTH_LONG).show();
    }


    /**
     * 判断是否是手机号
     * @param str
     * @return
     * @throws PatternSyntaxException
     */
    public static boolean isChinaPhone(String str)
            throws PatternSyntaxException {
        String regExp = "^((13[0-9])|(15[^4])|(166)|(17[0-8])|(18[0-9])|(19[8-9])|(147,145))\\d{8}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 是否是 全数字
     * @param str
     * @return
     * @throws PatternSyntaxException
     */
    public static  boolean isNum(String str)
            throws PatternSyntaxException {
        Pattern pattern = Pattern.compile("^-?[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    /**
     *  验证密码合法性
     *  不能全是数字或字母
     *  必须字母和数字组合
     * @param str
     * @return
     * @throws PatternSyntaxException
     */
    public static boolean isOkPassword(String str)
            throws PatternSyntaxException {
        String regExp = "(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    //获取版本号(内部识别号)
    public static int getVersionCode(Context context) {
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return pi.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 判断service是否在运行
     * @param context
     * @param cls
     * @return
     */
    public static boolean isServiceRunning(Context context, Class cls) {
        if (cls==null) {
            return false;
        }
        ActivityManager myManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>) myManager
                .getRunningServices(Integer.MAX_VALUE);
        for (int i = 0; i < runningService.size(); i++) {
            if (runningService.get(i).service.getClassName()
                    .equals(cls.getCanonicalName())) {
                return true;
            }
        }
        return false;
    }


    /**
     * 字节单位转换
     * @param size
     * @return
     */
    public static String getPrintSize(long size) {
        //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            return String.valueOf(size) + "B";
        } else {
            size = size / 1024;
        }
        //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (size < 1024) {
            return String.valueOf(size) + "KB";
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "MB";
        } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            return String.valueOf((size / 100)) + "."
                    + String.valueOf((size % 100)) + "GB";
        }
    }

    /**
     * byte to mb 保留两位
     * @param size
     * @return
     */
    public static float getByteToMb(float size) {
        return getByteToMb((long)size);
    }
    public static float getByteToMb(long size) {
        float s = size / 1024 / 1024;
        float num = (float) (Math.round(s * 100) / 100);
        return num;
    }

    /**
     * 判断字符串是否为空
     * @param str
     * @return
     */
    public static String fitterNull(String str) {
        if (StringUtil.isEmpty(str) || str.equals("null")) {
            return "";
        }
        return str;
    }

    //判断是否为空(有些字段返回字符串null)
    public static boolean isNull(String str) {
        if (StringUtil.isEmpty(str) || str.equals("null")) {
            return true;
        }
        return false;
    }

    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */
    public static String getDeviceBrand() {
        return Build.BRAND;
    }

    /**
     * 获取手机型号
     * @return
     */
    public static String getSystemModel() {
        return Build.MODEL;
    }

    public static String getOSVersion(){
        return Build.VERSION.RELEASE;
    }

    /**
     * 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
     *
     * @return 获取手机唯一标识
     */
    public static String getDeviceUUID(Context ctx) {
        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
        if (tm != null) {
            if (ActivityCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                return null;
            }
            String serialNumber = Build.SERIAL;
            UUID deviceUuid = new UUID(serialNumber.hashCode(), ((long)tm.getDeviceId().hashCode() << 32));
            return deviceUuid.toString();
        }
        return null;
    }

    /**
     * 判断GPS是否开启，GPS或者AGPS开启一个就认为是开启的
     * @param context
     * @return true 表示开启
     */
    public static final boolean isOPenGPS(final Context context) {
        LocationManager locationManager
                = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        // 通过GPS卫星定位，定位级别可以精确到街（通过24颗卫星定位，在室外和空旷的地方定位准确、速度快）
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        // 通过WLAN或移动网络(3G/2G)确定的位置（也称作AGPS，辅助GPS定位。主要用于在室内或遮盖物（建筑群或茂密的深林等）密集的地方定位）
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return true;
        }
        return false;
    }
    /**
     * 强制帮用户打开GPS
     * @param context
     */
    public static final void openGPS(Context context) {
        Intent GPSIntent = new Intent();
        GPSIntent.setClassName("com.android.settings",
                "com.android.settings.widget.SettingsAppWidgetProvider");
        GPSIntent.addCategory("android.intent.category.ALTERNATIVE");
        GPSIntent.setData(Uri.parse("custom:3"));
        try {
            PendingIntent.getBroadcast(context, 0, GPSIntent, 0).send();
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
    }



    /**
     * 检查是否需要更新
     * 0 不需要更新
     * 1 需要强制更新
     * 2 需要可选更新
     * @param context
     * @param newVersion
     * @return
     */
    public static int checkVersion(Context context, String newVersion){
        String currentVersion = getVersionName(context);
        int newInt = getVersionCode(newVersion);
        int currentInt = getVersionCode(currentVersion);
        newVersion = newVersion.replaceAll("\\.", "");
        currentVersion = currentVersion.replaceAll("\\.", "");
        if(!currentVersion.equals(newVersion)){
            try {
                //新版本低于当前版本也不提示更新
                int newVersionInt = Integer.parseInt(newVersion);
                int currentVersionInt = Integer.parseInt(currentVersion);
                if(currentVersionInt>newVersionInt){
                    return 0;
                }
            }catch (Exception e){}
            if(newInt>currentInt){
                return 1;
            }else{
                return 2;
            }
        }
        return 0;
    }
    /**
     * 将版本转成版本号方便比较大小
     * @param version
     * @return
     */
    public static int getVersionCode(String version){
        version = version.substring(0, version.indexOf(".",version.indexOf(".")+1 ));
        version = version.replaceAll("\\.", "");
        try{
            return Integer.parseInt(version);
        }catch(Exception e){

        }
        return 0 ;
    }
    public static String getVersionName(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionName+(BaseConst.ENVIR== BaseConst.Envir.DEVELPOER?" (内测版)":"");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "1.0.0";
        }
    }

    /**
     * 数组转列表
     * @param str
     * @return
     */
    public static List<String> strArrayToList(String[] str){
        List<String> arr = new ArrayList<>();
        if(str!=null){
            for(String s:str){
                arr.add(s);
            }
        }
        return arr;
    }


    /**
     *  涉及到使用了底层Native库的功能，先调用此方法检查一些设备是否支持
     *  不支持就弹个窗提示一下
     *  防止兼容性问题报错闪退
     *
     *  检查是否支持ABI
     * @param activity
     * @param c
     */
    public static void checkABICanSupport(final Activity activity, final CheckAPICanSupportBack c){
        String CUP_ABI = Build.CPU_ABI;
        if("armeabi".equals(CUP_ABI)||"armeabi-v7a".equals(CUP_ABI)||"arm64-v8a".equals(CUP_ABI)){
           c.support();
        }else{
            AlertDialog alertDialog = new AlertDialog(activity);
            alertDialog.setTitle("系统提示");
            alertDialog.setContent("很抱歉,"+activity.getString(R.string.app_name)+"所依赖的底层技术只支持ARM系列处理器的设备,暂不支持您的"+CUP_ABI+"设备,该功能暂时无法使用！");
            alertDialog.setSubmitTxt("确定");
            alertDialog.setCancelTxt("关闭");
            alertDialog.setOnDismissListener(dialogInterface -> c.notSupport());
            alertDialog.show(0, Gravity.CENTER);
        }
    }
    public interface CheckAPICanSupportBack{
        void support();
        void notSupport();
    }

    /**
     *  获取状态栏高度
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        int height = resources.getDimensionPixelSize(resourceId);
        return height;
    }

    /**
     * 将一串文字每个字之间加一个空格
     * @param para
     * @return
     */
    public static String appendSpace(String para){
        if(para==null){
            return "";
        }
        int length = para.length();
        char[] value = new char[length << 1];
        for (int i=0, j=0; i<length; ++i, j = i << 1) {
            value[j] = para.charAt(i);
            value[1 + j] = ' ';
        }
        String v = new String(value);
        return v.substring(0,v.length()-1);
    }

    /**
     * 获取屏幕宽高
     * @param activity
     * @return
     */
    public static int[] getScreenSize(Activity activity){
        DisplayMetrics metric = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getRealMetrics(metric);
        int width = metric.widthPixels; // 宽度（PX）
        int height = metric.heightPixels; // 高度（PX）
        return new int[]{width,height};
    }


    /**
     *  拨打电话
     * @param context
     * @param tel
     */
    public static void callTel(Context context,String tel){
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + tel);
        intent.setData(data);
        context.startActivity(intent);
    }

    /**
     * 获取根h5目录地址
     * @param activity
     * @return
     */
    public static String getWebRoot(Activity activity){
        String url = activity.getIntent().getStringExtra("url");
        if(StringUtil.isEmpty(url)){
            url = "index.html";//默认页 index
        }
        //非http处理
        if(!url.startsWith("http://")
                &&!url.startsWith("https://")){
            url = getH5Url(url);
        }
        return url;
    }


    /**
     * 检查是否有新版本路径
     * @return
     */
    public static boolean checkHasNewPath(){
        String newVersinPath = SharedPreferencesUtil.getData(BaseConst.NEW_VERSION_LOAD_PATH,"");
        if(!StringUtil.isEmpty(newVersinPath)){
            return true;
        }
        return false;
    }

    /**
     *  获取h5 的 url
     * @param url
     * @return
     */
    public static String getH5Url(String url){
        //有新版本的话 打开新版本的页面
        if(checkHasNewPath()){
            return "content://"+BaseApp.getApp().getPackageName()+".fileProvider/files/"+url;
        }else{
            return "file:///android_asset/"+url;
        }
    }

    /**
     *  加载H5配置信息
     * @param context
     * @param reload
     */
    public static void loadConfig(Context context,boolean reload){
        boolean canLoad = false;
        if(ApiEngine.h5AppConfig==null){
            canLoad = true;
        }
        if(reload){
            canLoad = true;
        }
        if(canLoad){
            String config ="";
            if(CommonUtil.checkHasNewPath()){
                String url =  FileUtil.getNewH5VersionPath()+"config.json";
                config=  FileUtil.readFile(url);
            }else{
                config =  FileUtil.getFromAssets(context, "config.json");
            }
            LogUtil.e("h5AppConfig",config);
            ApiEngine.h5AppConfig = JsonUtil.jsonToBean(config,H5AppConfig.class);
        }
    }

    /**
     *  拍照
     * @param context
     * @param backcode
     */
    public static String takePhoto(Activity context,int backcode){
            Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//打开相机的Intent
            if(takePhotoIntent.resolveActivity(context.getPackageManager())!=null){//这句作用是如果没有相机则该应用不会闪退，要是不加这句则当系统没有相机应用的时候该应用会闪退
                File imageFile = createImageFile(context);//创建用来保存照片的文件
                if(imageFile!=null){
                    Uri mImageUri;
                    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
                        /*7.0以上要通过FileProvider将File转化为Uri*/
                        mImageUri = FileProvider.getUriForFile(context, BaseApp.getApp().getPackageName()+".fileProvider",imageFile);
                    }else {
                        /*7.0以下则直接使用Uri的fromFile方法将File转化为Uri*/
                        mImageUri = Uri.fromFile(imageFile);
                    }
                    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri);//将用于输出的文件Uri传递给相机
                    context.startActivityForResult(takePhotoIntent, backcode);//打开相机
                    return imageFile.getPath();
                }
            }
            return null;
        }
        /**
         * @return 创建的图片文件
         */
        private static File createImageFile(Context context) {
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            String imageFileName = "JPEG_"+timeStamp+"_";
            File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File imageFile = null;
            try {
                imageFile = File.createTempFile(imageFileName,".jpg",storageDir);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return imageFile;
        }

    /**
     *  打开相册
     * @param activity
     * @param backcode
     */
        public static void openPhoto(Activity activity,int backcode) {
            Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);
            openAlbumIntent.setType("image/*");
            activity.startActivityForResult(openAlbumIntent, backcode);//打开相册
        }
}
